home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- * ClassAct Comprehensive Demo Program
- * Copyright © 1995 Osma Ahvenlampi
- *
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include <intuition/gadgetclass.h>
- #include <intuition/icclass.h>
- #include <libraries/gadtools.h>
- #include <graphics/gfxbase.h>
- #include <graphics/text.h>
- #include <graphics/gfxmacros.h>
- #include <utility/tagitem.h>
- #include <workbench/startup.h>
- #include <workbench/workbench.h>
-
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/diskfont.h>
- #include <proto/utility.h>
- #include <proto/wb.h>
- #include <proto/icon.h>
-
- #include <classact.h>
- #include <classact_lib.h>
- #include <clib/classact_lib_protos.h>
-
- void __stdargs kprintf(const char *, ...);
-
- /* a simple button */
- #define Button(a) ButtonObject, GA_Text, a, ButtonEnd
- #define DButton(a) ButtonObject, GA_Text, a, GA_Disabled, TRUE, ButtonEnd
-
- /**************************************************************************
- * Some label arrays for the gadgets in this demo.
- */
-
- static STRPTR objtypes[] =
- {
- "Exec",
- "Image",
- "Sound",
- "Menu",
- "Icon",
- "Dock",
- "Access",
- NULL
- };
-
- static STRPTR objnames[] =
- {
- "ToolManager",
- "ScreenMode",
- "WBPattern",
- NULL
- };
-
- /*************************************************************************
- * Gadget list
- * This wouldn't be strictly necessary, but it's an easy way of keeping
- * the gadget pointers for when we need to access the gadgets.
- */
- typedef enum { G_ObjType = 1, G_ObjList, G_Top, G_Up, G_Down, G_Bottom,
- G_Sort, G_New, G_Edit, G_Copy, G_Remove, G_Help, G_Save, G_Use,
- G_Test, G_Cancel, G_MAX } GadgetIDs;
-
- struct Gadget *GL[G_MAX+1];
-
- /*************************************************************************
- * ReadArgs
- */
-
- #define TEMPLATE "S=SIMPLEREFRESH/S,NC=NOCAREREFRESH/S,ND=NDEFER/S"
- LONG ARG[3];
- typedef enum { A_Simple, A_NoCare, A_NoDefer } Args;
-
- /*************************************************************************
- * App message hook.
- * Workbench App messages can be caught with a callback hook such as this.
- * We'll not worry about the app message type in this hook. Objects dropped
- * on the window or on the icon (while iconified) will be added to the
- * listview.
- */
-
- void __asm __saveds AppMsgFunc( register __a0 struct Hook *Hook,
- register __a2 Object *Window,
- register __a1 struct AppMessage *Msg )
- {
- struct Window *Win;
- struct WBArg *arg = Msg->am_ArgList;
- LONG i = Msg->am_NumArgs;
- struct List *l = Hook->h_Data;
- struct Node *n;
- UBYTE name[256];
-
- GetAttr( WINDOW_Window, Window, (ULONG *)&Win );
-
- /* Detach the list for modifications.
- */
- SetGadgetAttrs( GL[G_ObjList], Win, NULL, LISTBROWSER_Labels, ~0, TAG_END );
-
- while (i--)
- {
- /* Add the name of the icon to the listview. ListBrowser can copy the
- * text into an internal buffer and thus let us not worry about the
- * pointer validity.
- */
-
- NameFromLock( arg->wa_Lock, name, sizeof(name) );
- AddPart( name, arg->wa_Name, sizeof(name) );
-
- if (n = AllocListBrowserNode( 1, LBNCA_CopyText, TRUE, LBNCA_Text, name, TAG_END ))
- AddTail( l, n );
-
- arg++;
- }
-
- /* Reattach the list */
- SetGadgetAttrs( GL[G_ObjList], Win, NULL, LISTBROWSER_Labels, l, TAG_END );
- }
-
- /*************************************************************************
- * Main Program
- */
- int
- main(void)
- {
- struct List *objlist;
- struct List *typelist;
- struct RDArgs *args;
- struct MsgPort *appport;
-
- if (!ButtonBase) /* force it open */
- return 30;
-
- if (!(args = ReadArgs(TEMPLATE, ARG, NULL)))
- return 20;
-
- Printf("%seferred %s refresh %s\n", ARG[A_NoDefer] ? "Non-d" : "D", ARG[A_Simple] ? "Simple" : "Smart", ARG[A_NoCare] ? "(NoCare)" : "");
-
- objlist = BrowserNodesA( objnames );
- typelist = ChooserLabelsA( objtypes );
-
- /* By providing a message port you enable windowclass to handle iconification
- * and appwindows. This port can shared by all the windows of your application.
- */
- appport = CreateMsgPort();
-
- if (objlist && typelist && appport)
- {
- struct Gadget *MainLayout;
- Object *Window;
-
- struct Hook apphook;
- apphook.h_Entry = (ULONG (* )())AppMsgFunc;
- apphook.h_SubEntry = NULL;
- apphook.h_Data = objlist;
-
- /* Create a Window object with a Layout. When Window is asked to open itself,
- * it will calculate how much space the Layout needs and size itself accordingly.
- */
-
- Window = WindowObject,
-
- /* these tags describe the window
- */
-
- WA_IDCMP, IDCMP_RAWKEY,
- WA_Top, 20,
- WA_Left, 20,
- WA_SizeGadget, TRUE,
- WA_DepthGadget, TRUE,
- WA_DragBar, TRUE,
- WA_CloseGadget, TRUE,
- WA_Activate, TRUE,
-
- /* About window refreshes:
- * Because WindowClass and LayoutClass can, when used together, change the
- * normal Intuition practise of refreshing gadgets in the input.device context,
- * some rules about the refresh system change.
- * Deferred refresh works in both smart and simple refresh windows, but
- * if nocarerefresh is used, Intuition does not retain the damage regions
- * and any window damage will force the whole window to be refreshed.
- * This demo allows you to try combinations of refresh types.
- * In the normal case you can ignore this and let WindowClass and the user
- * decide what kind of refreshes they want. Nocare refresh can be
- * combined with smart refresh to provide a fast, but somewhat more memory
- * hungry refresh method. Simple refresh can save some memory but it's
- * slower.
- */
-
- WA_SimpleRefresh, ARG[A_Simple],
- WA_NoCareRefresh, ARG[A_NoCare],
- WA_SmartRefresh, !ARG[A_Simple],
-
- WA_Title, "ClassAct layout.gadget Example (ToolManager preferences mockup)",
- WA_ScreenTitle, "ClassAct Copyright 1995 Phantom Development LLC.",
-
- /* Turn on gadget help in the window
- */
-
- WINDOW_GadgetHelp, TRUE,
-
- /* Add an iconification gadget. If you have this, you must listen to
- * WMHI_ICONIFY.
- */
-
- WINDOW_IconifyGadget, TRUE,
-
- /* This message port lets windowclass handle the icon and appwindow.
- */
-
- WINDOW_AppPort, appport,
- WINDOW_AppWindow, TRUE,
- WINDOW_AppMsgHook, &apphook,
-
- /* The windowclass will automatically free the DiskObject used when
- * iconifying the window. If you do not provide a valid DiskObject,
- * windowclass will try to use env:sys/def_window.info or the default
- * project icon.
- */
-
- WINDOW_Icon, GetDiskObject( "LayoutExample" ),
- WINDOW_IconTitle, "ClassAct Example",
-
- /* Below is the layout of the window
- */
-
- WINDOW_ParentGroup, MainLayout = VGroupObject,
- LAYOUT_SpaceOuter, TRUE,
- LAYOUT_BevelStyle, BVS_THIN,
-
- /* this tag instructs layout.gadget to defer GM_LAYOUT and GM_RENDER and ask
- * the windowclass to do them. This lessens the load on input.device
- */
- LAYOUT_DeferLayout, !ARG[A_NoDefer],
-
- /* A 1-of-n chooser using the labels list we made from the label array earlier
- */
-
- StartMember, GL[G_ObjType] = ChooserObject,
- CHOOSER_Labels, typelist,
- EndMember,
- MemberLabel("_Object Type"),
-
- /* Objects can be given arbitary weights within groups, and layout.gadget
- * will distribute space relative to the total weight of the group.
- * Here we set the button column to 0 weight which means minimum space.
- * Thus the listview gets all available extra space.
- */
-
- StartHGroup, BAligned,
- StartMember, GL[G_ObjList] = ListBrowserObject,
- LISTBROWSER_Labels, objlist,
- LISTBROWSER_ShowSelected, TRUE,
- EndMember,
-
- StartVGroup,
- StartMember, GL[G_Top] = DButton("Top"),
- StartMember, GL[G_Up] = DButton("Up"),
- StartMember, GL[G_Down] = DButton("Down"),
- StartMember, GL[G_Bottom] = DButton("Bottom"),
- StartMember, GL[G_Sort] = Button("So_rt"),
- EndGroup,
- CHILD_WeightedWidth, 0,
-
- /* One way to keep the buttons constant size is to set the
- * group to stay at minimum size with a weight of 0. We could
- * also set the weight of each of the buttons to 0. That way
- * extra space would be distributed between the buttons
- * instead of all below. This looks better.
- */
-
- CHILD_WeightedHeight, 0,
- EndGroup,
-
- /* two rows of buttons. EvenSized instructs layout.gadget that it
- * should make sure the minimum size of each matches, so that we
- * get four neat columns.
- * Again the weight is set to 0. When the window is resized, all
- * space is given to the listview.
- */
-
- StartHGroup, EvenSized,
- StartMember, GL[G_New] = Button("_New..."),
- StartMember, GL[G_Edit] = DButton("_Edit..."),
- StartMember, GL[G_Copy] = DButton("Co_py"),
- StartMember, GL[G_Remove] = DButton("Remove"),
- EndGroup,
- CHILD_WeightedHeight, 0,
-
- StartHGroup, EvenSized,
- StartMember, GL[G_Save] = Button("_Save"),
- StartMember, GL[G_Use] = Button("_Use"),
- StartMember, GL[G_Test] = Button("_Test"),
- StartMember, GL[G_Cancel] = Button("_Cancel"),
- EndGroup,
- CHILD_WeightedHeight, 0,
-
- StartMember, GL[G_Help] = ButtonObject,
- GA_ReadOnly, TRUE,
- GA_Text, "Welcome to ClassAct demo!",
- EndMember,
- CHILD_WeightedHeight, 0,
- EndGroup,
- EndWindow;
-
- if (Window)
- {
- /* Window pointer cache.
- */
-
- struct Window *Win;
-
- /* Finish the gadgetarray initialisation. Set gadget IDs and release verify.
- * This is one way of avoiding boring repetition in the layout description
- * taglist itself.
- */
-
- {
- LONG i = 1;
- do SetAttrs(GL[i], GA_ID, i, GA_RelVerify, TRUE, TAG_END);
- while (GL[++i]);
- }
-
- if (Win = CA_OpenWindow( Window ))
- {
- ULONG wsig, asig = 1L << appport->mp_SigBit;
- BOOL done = FALSE;
-
- /* Now that the window has been opened, we can get the signal mask
- * of its user port. If the program supported iconification and didn't
- * use a shared IDCMP port between all windows, this signal bit
- * would have to be re-queried before each Wait().
- */
-
- GetAttr( WINDOW_SigMask, Window, &wsig );
-
- while (done == FALSE)
- {
- ULONG sig = Wait(wsig | asig | SIGBREAKF_CTRL_C);
- ULONG result;
- UWORD code;
-
- if (sig & (wsig | asig))
- {
- /* Messages waiting at the window's IDCMP port. Loop at WM_HANDLEINPUT
- * until all have been processed.
- */
-
- while ((result = CA_HandleInput(Window,&code)) != WMHI_LASTMSG)
- {
- /* The return code of this method is two-part. The upper word describes the
- * class of the message (gadgetup, menupick, closewindow, iconify, etc),
- * and the lower word is a class-defined ID, currently in use in the
- * gadgetup and menupick return codes.
- * Switch on the class, then on the ID.
- */
-
- switch(result & WMHI_CLASSMASK)
- {
- case WMHI_GADGETUP:
-
- /* OK, got a gadgetup from something. Lets find out what the something is.
- * The code WORD to which a pointer was passed to WM_HANDLEINPUT has been
- * set to the Code value from the IDCMP_GADGETUP, in case we need it.
- */
-
- switch(result & WMHI_GADGETMASK)
- {
- case G_ObjList:
- /* User clicked on the listview
- */
- {
- static ULONG ids[] = { G_Top, G_Up, G_Down, G_Bottom, G_Edit, G_Copy, G_Remove, 0 };
- ULONG i, dis = FALSE;
-
- if (code == ~0) /* no node was selected */
- dis = TRUE;
-
- for ( i = 0 ; ids[i] ; i++ )
- {
- SetGadgetAttrs( GL[ids[i]], Win, NULL, GA_Disabled, dis, TAG_END );
- RefreshGList( GL[ids[i]], Win, NULL, 1 );
- }
-
- break;
- }
- }
- break;
-
- case WMHI_GADGETHELP:
- {
- STRPTR helptext;
-
- /* A gadget help message informs the application about the gadget
- * under the mouse pointer. The code WORD is set to the value the
- * gadget returned. Result code contains the ID of the gadget,
- * or NULL (not in the window) or WMHI_GADGETMASK (not over a gadget).
- */
-
- switch(result & WMHI_GADGETMASK)
- {
- case G_ObjType:
- helptext = "Choose object type";
- break;
- case G_ObjList:
- helptext = "Choose object to modify";
- break;
- case G_Top:
- helptext = "Move object to top";
- break;
- case G_Up:
- helptext = "Move object upwards";
- break;
- case G_Down:
- helptext = "Move object downwards";
- break;
- case G_Bottom:
- helptext = "Move object to bottom";
- break;
- case G_Sort:
- helptext = "Sort object list";
- break;
- case G_New:
- helptext = "Create new object";
- break;
- case G_Edit:
- helptext = "Edit object";
- break;
- case G_Copy:
- helptext = "Make a new copy of object";
- break;
- case G_Remove:
- helptext = "Delete the object";
- break;
- case G_Help:
- helptext = "Hey there ;)";
- break;
- case G_Save:
- helptext = "Save settings";
- break;
- case G_Use:
- helptext = "Use these settings";
- break;
- case G_Test:
- helptext = "Test these settings";
- break;
- case G_Cancel:
- helptext = "Cancel changes";
- break;
- default:
- helptext = "";
- break;
- }
- if (SetGadgetAttrs( GL[G_Help], Win, NULL, GA_Text, helptext, TAG_END ))
- RefreshGList(GL[G_Help], Win, NULL, 1);
- }
- break;
-
- case WMHI_CLOSEWINDOW:
- /* The window close gadget was hit. Time to die...
- */
- done = TRUE;
- break;
-
- case WMHI_ICONIFY:
- /* Window requests that it be iconified. Handle this event as
- * soon as possible. The window is not iconified automatically to
- * give you a chance to make note that the window pointer will be
- * invalid before the window closes. It also allows you to free
- * resources only needed when the window is open, if you wish to.
- */
- if (CA_Iconify( Window ))
- Win = NULL;
- break;
-
- case WMHI_UNICONIFY:
- /* The window should be reopened. If you had free'd something
- * on iconify, now is the time to re-allocate it, before calling
- * CA_OpenWindow.
- */
- Win = CA_OpenWindow( Window );
- break;
- }
- }
- }
- else if (sig & SIGBREAKF_CTRL_C)
- {
- done = TRUE;
- }
- }
- /* Close the window and dispose of all attached gadgets
- */
- DisposeObject( Window );
- }
- }
- }
-
- if (appport)
- DeleteMsgPort(appport);
-
- /* NULL is valid input for these helper functions, so no need to check.
- */
- FreeChooserLabels( typelist );
- FreeBrowserNodes( objlist );
-
- FreeArgs(args);
- }
-